package com.iot.gateway.tsl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.iot.gateway.tsl.mapper.TslPropertyAttrMapper;
import com.iot.gateway.tsl.mapper.TslPropertyMapper;
import com.iot.gateway.tsl.qo.PropertyQo;
import com.iot.gateway.tsl.model.TslPropertyAttrEntity;
import com.iot.gateway.tsl.model.TslPropertyEntity;
import com.iot.gateway.tsl.service.TslPropertyService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class TslPropertyServiceImpl implements TslPropertyService {

    private final TslPropertyMapper propertyMapper;
    private final TslPropertyAttrMapper attrMapper;

    public TslPropertyServiceImpl(TslPropertyMapper propertyMapper,
                                  TslPropertyAttrMapper attrMapper) {
        this.propertyMapper = propertyMapper;
        this.attrMapper     = attrMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProperty(String deviceId, PropertyQo property) {
        // 1. 插入固定字段
        TslPropertyEntity entity = new TslPropertyEntity();
        entity.setPropertyId(Optional.ofNullable(property.getId())
                .filter(id -> !id.isEmpty())
                .orElse(UUID.randomUUID().toString()));
        entity.setDeviceId(deviceId);
        entity.setPropertyName(property.getName());
        entity.setDataType(property.getPropertyType());
        entity.setAccessMode(property.getReadWrite());
        entity.setMeasureUnit(property.getUnit());
        entity.setDefaultValue(property.getDefaultValue() != null
                ? property.getDefaultValue().toString()
                : null);
        propertyMapper.insert(entity);

        // 2. 插入动态字段
        if (property.getCustomFields() != null) {
            List<TslPropertyAttrEntity> attrs =
                    property.getCustomFields().entrySet().stream()
                            .map(e -> {
                                TslPropertyAttrEntity attr = new TslPropertyAttrEntity();
                                attr.setPropertyId(entity.getPropertyId());
                                attr.setAttrKey(e.getKey());
                                attr.setAttrValue(Objects.toString(e.getValue(), null));
                                return attr;
                            })
                            .collect(Collectors.toList());
            attrs.forEach(attrMapper::insert);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProperty(String deviceId, PropertyQo property) {
        // 1. 更新固定字段
        TslPropertyEntity entity = new TslPropertyEntity();
        entity.setPropertyId(property.getId());
        entity.setDeviceId(deviceId);
        entity.setPropertyName(property.getName());
        entity.setDataType(property.getPropertyType());
        entity.setAccessMode(property.getReadWrite());
        entity.setMeasureUnit(property.getUnit());

        entity.setDefaultValue(property.getDefaultValue() != null
                ? property.getDefaultValue().toString()
                : null);
        propertyMapper.updateById(entity);

        // 2. 重建动态字段：先删后插
        attrMapper.delete(new LambdaQueryWrapper<TslPropertyAttrEntity>()
                .eq(TslPropertyAttrEntity::getPropertyId, property.getId()));

        if (property.getCustomFields() != null) {
            property.getCustomFields().forEach((k, v) -> {
                TslPropertyAttrEntity attr = new TslPropertyAttrEntity();
                attr.setPropertyId(property.getId());
                attr.setAttrKey(k);
                attr.setAttrValue(Objects.toString(v, null));
                attrMapper.insert(attr);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProperty(String deviceId, String propertyId) {
        // 删除扩展字段
        attrMapper.delete(new LambdaQueryWrapper<TslPropertyAttrEntity>()
                .eq(TslPropertyAttrEntity::getPropertyId, propertyId));
        // 删除固定字段
        propertyMapper.deleteById(propertyId);
    }

    @Override
    public List<PropertyQo> getProperties(String deviceId) {
        List<TslPropertyEntity> entities = propertyMapper.selectList(
                new LambdaQueryWrapper<TslPropertyEntity>()
                        .eq(TslPropertyEntity::getDeviceId, deviceId)
        );

        List<String> ids = entities.stream()
                .map(TslPropertyEntity::getPropertyId)
                .collect(Collectors.toList());
        List<TslPropertyAttrEntity> allAttrs = attrMapper.selectList(
                new LambdaQueryWrapper<TslPropertyAttrEntity>()
                        .in(TslPropertyAttrEntity::getPropertyId, ids)
        );

        Map<String, List<TslPropertyAttrEntity>> grouped = allAttrs.stream()
                .collect(Collectors.groupingBy(TslPropertyAttrEntity::getPropertyId));

        return entities.stream().map(e -> {
            PropertyQo dto = new PropertyQo();
            dto.setId(e.getPropertyId());
            dto.setName(e.getPropertyName());
            dto.setPropertyType(e.getDataType());
            dto.setReadWrite(e.getAccessMode());
            dto.setUnit(e.getMeasureUnit());
            dto.setDefaultValue(e.getDefaultValue());
            Map<String,Object> custom = new HashMap<>();
            grouped.getOrDefault(e.getPropertyId(), Collections.emptyList())
                    .forEach(a -> custom.put(a.getAttrKey(), a.getAttrValue()));
            dto.setCustomFields(custom);
            return dto;
        }).collect(Collectors.toList());
    }
}
